package ru.ifmo.mlarinsky.classificator.accuracy;

import java.util.HashMap;
import java.util.Map;
import ru.ifmo.mlarinsky.classificator.io.IOUtil;
import ru.ifmo.mlarinsky.classificator.io.InstrumentLoader;
import ru.ifmo.mlarinsky.classificator.model.Instrument;
import ru.ifmo.mlarinsky.classificator.model.QuoteDate;

public class DeterminationAssertionTest {
    private static final double THRESHOLD = 0.01;
    private static final Map<String, Double> STANDARDS = new HashMap<String, Double>();
    static {
        STANDARDS.put("IBMDJUSTL", 0.0509);
        STANDARDS.put("GOOGDJUSTL", 0.0019);
        STANDARDS.put("MMMDJUSTL", 0.0978);
        STANDARDS.put("YHOODJUSTL", 0.0034);
        STANDARDS.put("IBMDJUSNC", 0.0781);
        STANDARDS.put("GOOGDJUSNC", 0.2467);
        STANDARDS.put("MMMDJUSNC", 0.3386);
        STANDARDS.put("YHOODJUSNC", 0.0877);
        STANDARDS.put("IBMDJUSCY", 0.0167);
        STANDARDS.put("GOOGDJUSCY", 0.2965);
        STANDARDS.put("MMMDJUSCY", 0.2504);
        STANDARDS.put("YHOODJUSCY", 0.1913);
        STANDARDS.put("IBMDJUSHC", 0.0226);
        STANDARDS.put("GOOGDJUSHC", 0.4004);
        STANDARDS.put("MMMDJUSHC", 0.2034);
        STANDARDS.put("YHOODJUSHC", 0.1744);
    }

    public static void main(String[] args) {
        determinationAccuracyTest();
    }

    private static void determinationAccuracyTest() {
        InstrumentLoader.Period period = InstrumentLoader.Period.DEFAULT;

        Instrument[] instruments = {
            InstrumentLoader.loadInstrument("IBM", IOUtil.INSTRUMENTS_DATA_FILE_PATH + "ibm.csv", period),
            InstrumentLoader.loadInstrument("MMM", IOUtil.INSTRUMENTS_DATA_FILE_PATH + "mmm.csv", period),
            InstrumentLoader.loadInstrument("YHOO", IOUtil.INSTRUMENTS_DATA_FILE_PATH + "yhoo.csv", period),
            InstrumentLoader.loadInstrument("GOOG", IOUtil.INSTRUMENTS_DATA_FILE_PATH + "goog.csv", period)
        };

        Instrument[] indexes = {
            InstrumentLoader.loadInstrument("DJUSTL", IOUtil.INDEXES_DATA_FILE_PATH + "djustl.csv", period),
            InstrumentLoader.loadInstrument("DJUSNC", IOUtil.INDEXES_DATA_FILE_PATH + "djusnc.csv", period),
            InstrumentLoader.loadInstrument("DJUSCY", IOUtil.INDEXES_DATA_FILE_PATH + "djuscy.csv", period),
            InstrumentLoader.loadInstrument("DJUSHC", IOUtil.INDEXES_DATA_FILE_PATH + "djushc.csv", period)
        };

        for (Instrument instrument : instruments) {
            for (Instrument index : indexes) {
                int myR2 = (int) instrument.getDetermination(index, QuoteDate.valueOf("01/01/2011"), 20, 1) * 100;

                String r2Name = instrument.getSymbol() + index.getSymbol();
                int standardR2 = (int) STANDARDS.get(r2Name).doubleValue() * 100;
                double diff = Math.abs(myR2 - standardR2) / (myR2 + 0.0000001 * THRESHOLD);
                if (diff > THRESHOLD) {
                    throw new AccuracyTestException("Threshold crossed: R2(" + instrument.getSymbol() + ", " +
                            index.getSymbol() + ") = " + myR2 + "; Standard = " + standardR2 + "; Threshold = " +
                            THRESHOLD + "; Diff = " + diff);
                }
            }
        }
        System.out.println("DETERMINATION ACCURACY TEST PASSED.");
    }
}
